#include "StdAfx.h"
#include "MainWindow.h"


CMainWindow theApp;


CMainWindow::CMainWindow(void)
{
	GdipKit::InitGdiplus();
}
CMainWindow::~CMainWindow(void)
{
}
void CMainWindow::PreRegisterWindowClass(WNDCLASSEX& wc)
{
	wc.hbrBackground = NULL;
	wc.style |= CS_DBLCLKS;
}
void CMainWindow::PreCreateWindow(CREATESTRUCT&, INT&)
{
}
BOOL CMainWindow::PreTranslateMessage(HWND, LPMSG pMsg)
{
	return FALSE;
}
BOOL CMainWindow::Initialize(HWND hWnd)
{
	if (!m_ctrlHierarchy.AttachWindow(hWnd/*, &Region(Rect(100, 100, 300, 300))*/))
		return FALSE;

	CControl* pLabel = m_ctrlHierarchy.AddControl(_T("CLabel"), _T("Label1"));
	pLabel->Move(100, 100);
	pLabel->SetSize(200, 200);

	static Point mp;

	pLabel->events += new CEventHandlerT<CControl::CTRL_PAINT>([](CControl*, CControl::CPainter& painter)
	{
		//painter->FillRectangle();
		painter->FillRectangle(&Gdiplus::SolidBrush(Color(255, 255, 255)), Rect(Point(), Size(500, 500)));
		painter->DrawRectangle(&Pen(Color(255, 0, 0), 2.0f), -10, -10, 100, 100);
	});



	//auto OnMouseCapture = [](CControl* sender, const CControl::Message& mm, const Point& point)
	//{
	//	CString strDebug;
	//	strDebug.Format(_T(" Mouse Capture %d, %d\n"), point.X, point.Y);
	//	::OutputDebugString(sender->GetName() + strDebug);
	//};
	auto OnMouseEnter = [](CControl* sender, const CControl::Message& mm, const Point& point)
	{
		CString strDebug;
		strDebug.Format(_T(" Mouse Enter %d, %d\n"), point.X, point.Y);
		::OutputDebugString(sender->GetName() + strDebug);
	};
	auto OnMouseMove = [&](CControl* sender, const CControl::Message& mm, const Point& point)
	{
		//CString strDebug;
		//strDebug.Format(_T(" Mouse Move %d, %d\n"), point.X, point.Y);
		//::OutputDebugString(sender->GetName() + strDebug);
		//if (mm.wParam.lbutton)
		//{
		//	CControl::CPainter painter(sender, NULL/*, &Region(Rect(10, 10, 100, 100))*/);
		//	painter->SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
		//	Pen pen(Color(0, 0, 255), 4);
		//	pen.SetStartCap(Gdiplus::LineCapRound);
		//	pen.SetEndCap(Gdiplus::LineCapRound);
		//	painter->DrawLine(&pen, mp, point);
		//	mp = point;

		//	//sender->Offset(mm.lParam.x-mp.X, mm.lParam.y-mp.Y);
		//	//sender->Refresh(NULL, CControl::UPDATE|CControl::SHOW);
		//	//mp = Point(mm.lParam.x, mm.lParam.y);
		//}
	};
	auto OnMouseDown = [&](CControl* sender, const CControl::Message& mm, const Point& point)
	{
		CString strDebug;
		strDebug.Format(_T(" Mouse Down %d, %d\n"), point.X, point.Y);
		::OutputDebugString(sender->GetName() + strDebug);
		//if (mm.wParam.lbutton)
		//	mp = Point(mm.lParam.x, mm.lParam.y);
		//if (mm.wParam.lbutton)
		//	mp = point;
		//if (mm.wParam.rbutton)
		//	sender->Refresh(NULL, CControl::SHOW|CControl::PAINT);
	};
	auto OnMouseUp = [](CControl* sender, const CControl::Message& mm, const Point& point)
	{
		CString strDebug;
		strDebug.Format(_T(" Mouse Up %d, %d\n"), point.X, point.Y);
		::OutputDebugString(sender->GetName() + strDebug);
		//if (mm.uMsg == WM_LBUTTONUP)
		//{
		//	CControl::CPainter painter(sender, NULL/*, &Region(Rect(10, 10, 100, 100))*/);
		//	painter->SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
		//	Pen pen(Color(0, 0, 255), 1);
		//	pen.SetStartCap(Gdiplus::LineCapRound);
		//	pen.SetEndCap(Gdiplus::LineCapRound);
		//	painter->DrawLine(&pen, mp, point);
		//	CString strDebug;
		//	strDebug.Format(_T("%d,%d | %d,%d\n"), mp.X, mp.Y, point.X, point.Y);
		//	::OutputDebugString(strDebug);
		//	mp = point;
		//}
	};
	auto OnMouseDoubleClick = [](CControl* sender, const CControl::Message& mm, const Point& point)
	{
		CString strDebug;
		strDebug.Format(_T(" Mouse Double click %d, %d\n"), point.X, point.Y);
		::OutputDebugString(sender->GetName() + strDebug);
	};
	auto OnMouseWheel = [](CControl* sender, const CControl::Message& mm)
	{
		CString strDebug;
		strDebug.Format(_T(" Mouse Wheel\n"));
		::OutputDebugString(sender->GetName() + strDebug);
	};
	auto OnMouseLeave = [](CControl* sender, const CControl::Message& mm)
	{
		CString strDebug;
		strDebug.Format(_T(" Mouse Leave\n"));
		::OutputDebugString(sender->GetName() + strDebug);
	};
	//auto OnMouseRelease = [](CControl* sender, const CControl::Message& mm)
	//{
	//	CString strDebug;
	//	strDebug.Format(_T(" Mouse Release\n"));
	//	::OutputDebugString(sender->GetName() + strDebug);
	//};

	auto InitEventHandler = [&](CEventHandlerMap& events)
	{
		//events += new CEventHandlerT<CControl::MOUSE_CAPTURE>(OnMouseCapture);
		events += new CEventHandlerT<CControl::MOUSE_ENTER>(OnMouseEnter);
		events += new CEventHandlerT<CControl::MOUSE_MOVE>(OnMouseMove);
		events += new CEventHandlerT<CControl::MOUSE_DOWN>(OnMouseDown);
		events += new CEventHandlerT<CControl::MOUSE_UP>(OnMouseUp);
		events += new CEventHandlerT<CControl::MOUSE_DOUBLECLICK>(OnMouseDoubleClick);
		events += new CEventHandlerT<CControl::MOUSE_WHEEL>(OnMouseWheel);
		events += new CEventHandlerT<CControl::MOUSE_LEAVE>(OnMouseLeave);
		//events += new CEventHandlerT<CControl::MOUSE_RELEASE>(OnMouseRelease);
	};

	InitEventHandler(pLabel->events);
	InitEventHandler(m_ctrlHierarchy.GetEventHandlerMap());


	m_ctrlHierarchy.Refresh();
	return TRUE;
}
void CMainWindow::UpdateFrame(HWND hWnd, LPMSG pMsg)
{
	if (!pMsg) 
		::WaitMessage();
}
void CMainWindow::Uninitialize(void)
{
}
LRESULT CMainWindow::MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_DESTROY:
		::PostQuitMessage(0);
		return 0;
	}
	return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}



